<template>
   <view class="waterfall">
      <uv-sticky>
         <view style="padding: 10rpx 0; background-color: #fff">
            <uv-tabs
               :list="[{ name: '美食' }, { name: '文化' }, { name: '科技' }]"
               @click="tabChange"
            ></uv-tabs>
         </view>
      </uv-sticky>
      <view class="waterfall">
         <!-- #ifndef APP-NVUE -->
         <uv-waterfall
            ref="waterfall"
            v-model="list"
            :add-time="10"
            :left-gap="leftGap"
            :right-gap="rightGap"
            :column-gap="columnGap"
            @changeList="changeList"
            @remove="remove"
         >
            <!-- 第一列数据 -->
            <template v-slot:list1>
               <!-- 为了磨平部分平台的BUG，必须套一层view -->
               <view>
                  <view
                     v-for="(item, index) in list1"
                     :key="item.id"
                     class="waterfall-item"
                     @longpress="longHandle(item)"
                  >
                     <view class="waterfall-item__image" :style="imageStyle(item)">
                        <uv-image :src="item.image" :width="`${item.width}px`" />
                     </view>
                     <view class="waterfall-item__ft">
                        <view class="waterfall-item__ft__title">
                           <text class="value">{{ item.title }}</text>
                        </view>
                        <view class="waterfall-item__ft__desc uv-line-2">
                           <text class="value">{{ item.desc }}</text>
                        </view>
                        <view class="waterfall-item__ft__btn" v-if="index == 0">
                           <uv-button
                              text="异步修改"
                              type="primary"
                              size="small"
                              @click="edit(item)"
                           />
                        </view>
                     </view>
                  </view>
               </view>
            </template>
            <!-- 第二列数据 -->
            <template v-slot:list2>
               <!-- 为了磨平部分平台的BUG，必须套一层view -->
               <view>
                  <view v-for="(item, index) in list2" :key="item.id" class="waterfall-item">
                     <view class="waterfall-item__image" :style="imageStyle(item)">
                        <uv-image :src="item.image" :width="`${item.width}px`" />
                     </view>
                     <view class="waterfall-item__ft">
                        <view class="waterfall-item__ft__title">
                           <text class="value">{{ item.title }}</text>
                        </view>
                        <view class="waterfall-item__ft__desc uv-line-2">
                           <text class="value">{{ item.desc }}</text>
                        </view>
                     </view>
                  </view>
               </view>
            </template>
         </uv-waterfall>
         <uv-load-more :status="loadStatus"></uv-load-more>
         <!-- #endif -->
         <!-- #ifdef APP-NVUE -->
         <uv-waterfall
            column-count="2"
            left-gap="10"
            right-gap="10"
            column-gap="8"
            :height="waterfallHeight"
            @scrolltolower="init"
         >
            <cell v-for="(item, index) in list" class="waterfall-item-cell">
               <view class="waterfall-item">
                  <view class="waterfall-item__image">
                     <image
                        class="img"
                        :src="item.image"
                        mode="widthFix"
                        style="border-radius: 20rpx"
                     ></image>
                  </view>
                  <view class="waterfall-item__ft">
                     <view class="waterfall-item__ft__title">
                        <text class="value">{{ item.title }}</text>
                     </view>
                     <view class="waterfall-item__ft__desc uv-line-2">
                        <text class="value">{{ item.desc }}</text>
                     </view>
                  </view>
               </view>
               <view style="height: 4px; width: 4px"></view>
            </cell>
         </uv-waterfall>
         <!-- #endif -->
      </view>
   </view>
</template>

<script lang="ts" setup>
import { test } from '@/api';
import { computed, ref } from 'vue';
import { onHide, onLoad, onPullDownRefresh, onReachBottom } from '@dcloudio/uni-app';

// 类型定义
interface WaterfallItem {
   id: string;
   allowEdit?: boolean;
   image: string;
   w: number;
   h: number;
   width?: number;
   title: string;
   desc: string;
}

interface ImageData {
   url: string;
   width: number;
   height: number;
}

// 响应式数据
const list = ref<WaterfallItem[]>([]); // 瀑布流全部数据
const list1 = ref<WaterfallItem[]>([]); // 瀑布流第一列数据
const list2 = ref<WaterfallItem[]>([]); // 瀑布流第二列数据
const loadStatus = ref<'loadmore' | 'loading' | 'nomore'>('loadmore');
const leftGap = ref(10);
const rightGap = ref(10);
const columnGap = ref(10);

// refs
const waterfall = ref();

// 计算属性
const waterfallHeight = computed(() => {
   return uni.$uv.sys().windowHeight - Number(uni.$uv.getPx('100rpx'));
});

const imageStyle = computed(() => {
   return (item: WaterfallItem) => {
      const v = uni.upx2px(750) - leftGap.value - rightGap.value - columnGap.value;
      const w = v / 2;
      const rate = w / item.w;
      const h = rate * item.h;
      return {
         width: w + 'px',
         height: h + 'px',
      };
   };
});

// 预定义的图片尺寸配置（随机接口，每次获取不同图片）
const imageSizes: Omit<ImageData, 'url'>[] = [
   { width: 280, height: 350 },
   { width: 320, height: 480 },
   { width: 300, height: 400 },
   { width: 350, height: 280 },
   { width: 290, height: 420 },
   { width: 330, height: 500 },
   { width: 310, height: 380 },
   { width: 340, height: 460 },
   { width: 300, height: 360 },
   { width: 320, height: 440 },
   { width: 280, height: 380 },
   { width: 350, height: 420 },
];

// 示例标题和描述内容
const contentTemplates = {
   titles: [
      'uv-ui 现代化UI框架',
      '跨平台开发解决方案',
      'Vue3 + TypeScript 最佳实践',
      '高性能组件库设计',
      'uni-app 生态专用框架',
      '移动端优化组件',
      '响应式设计组件',
      '原生性能体验',
      '开箱即用的UI套件',
      '企业级组件解决方案',
   ],
   descriptions: [
      '基于Vue3和TypeScript构建的现代化UI框架，提供丰富的组件和优秀的开发体验',
      '一套代码，多端运行，支持iOS、Android、H5及各种小程序平台',
      '采用最新的Vue3 Composition API，结合TypeScript提供完整的类型支持',
      '精心设计的组件库，注重性能优化和用户体验，适用于各种业务场景',
      '专为uni-app生态打造，完美兼容各平台特性，提供一致的开发体验',
      '针对移动端优化的组件设计，支持触摸交互和手势操作',
      '灵活的主题定制和样式配置，满足不同项目的视觉需求',
      '底层优化确保原生级别的性能表现，流畅的动画和交互效果',
      '开箱即用的完整UI解决方案，快速构建美观的应用界面',
      '面向企业级应用的组件库，稳定可靠，支持大规模项目开发',
   ],
};

// 优化后的数据获取函数（每次获取新的随机图片）
const getData = async (): Promise<{ data: WaterfallItem[] }> => {
   try {
      // 生成数据
      const currentLength = list.value.length;
      const dataList: WaterfallItem[] = [];

      // 为每个项目获取随机图片和尺寸
      for (let i = 0; i < 20; i++) {
         const randomSizeIndex = Math.floor(Math.random() * imageSizes.length);
         const randomTitleIndex = Math.floor(Math.random() * contentTemplates.titles.length);
         const randomDescIndex = Math.floor(Math.random() * contentTemplates.descriptions.length);
         const itemIndex = currentLength + i + 1;

         // 每次都获取新的随机图片
         const { data } = await test();
         const selectedSize = imageSizes[randomSizeIndex];

         const item: WaterfallItem = {
            id: uni.$uv.guid(),
            allowEdit: i === 0, // 只有第一项可编辑
            image: data,
            w: selectedSize.width,
            h: selectedSize.height,
            title: `(${itemIndex}) ${contentTemplates.titles[randomTitleIndex]}`,
            desc: `${contentTemplates.descriptions[randomDescIndex]}`,
         };

         dataList.push(item);
      }

      // 模拟网络延迟
      await new Promise(resolve => setTimeout(resolve, Math.random() * 200 + 100));

      return { data: dataList };
   } catch (error) {
      // 返回空数据作为兜底
      return { data: [] };
   }
};

// 选项卡切换
const tabChange = (index: number) => {
   // #ifndef APP-NVUE
   waterfall.value?.clear();
   // #endif
   list.value = [];
   list1.value = [];
   list2.value = [];
   // 每次切换都会获取新的随机图片，无需缓存
   init();
};

// 这点非常重要：e.name在这里返回是list1或list2，要手动将数据追加到相应列
const changeList = (e: { name: string; value: WaterfallItem }) => {
   if (e.name === 'list1') {
      list1.value.push(e.value);
   } else if (e.name === 'list2') {
      list2.value.push(e.value);
   }
};

const init = async () => {
   loadStatus.value = 'loading';
   const { data } = await getData();
   list.value.push(...data);
   loadStatus.value = 'loadmore';
};

// 长按某项执行删除操作
const longHandle = (item: WaterfallItem) => {
   uni.showModal({
      title: '提示',
      content: '你确定删除该项？',
      success(res) {
         if (res.confirm) {
            waterfall.value?.remove(item.id);
         }
      },
   });
};

// 删除某项后返回对应id，根据id标识在列数据中手动删除该项数据
const remove = (id: string) => {
   list1.value.forEach((item, index) => {
      if (item.id == id) {
         list1.value.splice(index, 1);
      }
   });
   list2.value.forEach((item, index) => {
      if (item.id == id) {
         list2.value.splice(index, 1);
      }
   });
};

// 修改某项数据
const edit = (item: WaterfallItem) => {
   uni.showLoading({
      title: '修改中',
   });
   setTimeout(() => {
      item.title = 'uv-ui1.0';
      item.desc = '修改后的文本';
      uni.hideLoading();
   }, 1000);
};

// 生命周期钩子
onLoad(async () => {
   const { data } = await getData();
   list.value = data;
});

onHide(() => {
   // #ifndef APP-NVUE
   waterfall.value?.clear();
   // #endif
});

// 下拉刷新数据
onPullDownRefresh(async () => {
   list.value = [];
   // #ifndef APP-NVUE
   waterfall.value?.clear();
   // #endif
   list1.value = [];
   list2.value = [];
   await init();
   uni.showToast({
      icon: 'success',
      title: '刷新成功',
   });
   uni.stopPullDownRefresh();
});

// 触底加载更多
onReachBottom(async () => {
   if (loadStatus.value == 'loadmore') {
      await init();
   }
});
</script>
<style>
/* #ifndef APP-NVUE */
page {
   background: #f1f1f1;
}
/* #endif */
</style>
<style lang="scss" scoped>
@use '@toothdy/uvui-ts/libs/css/variable.scss';
$show-lines: 1;

.waterfall {
   background-color: #f1f1f1;
}
.waterfall-item {
   overflow: hidden;
   margin-top: 10px;
   border-radius: 8px;
   background: #fff;
   box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);

   &__image {
      width: 100%;
      overflow: hidden;
      border-radius: 8px 8px 0 0;

      image {
         width: 100%;
         height: auto;
         display: block;
      }
   }

   &__ft {
      padding: 5px;
      background: #fff;
      border-radius: 0 0 8px 8px;

      &__title {
         margin-bottom: 8px;
         line-height: 1.4;
         font-weight: 600;

         .value {
            font-size: 16px;
            color: #303133;
            line-height: 1.4;
            word-break: break-word;
         }
      }

      &__desc {
         margin-bottom: 10px;

         .value {
            font-size: 14px;
            color: #606266;
            line-height: 1.5;
            word-break: break-word;
         }
      }

      &__btn {
         padding: 8px 0;
      }
   }
}

/* #ifdef APP-NVUE */
.waterfall-item-cell {
   margin-bottom: 10px;
}

.img {
   width: 100%;
   border-radius: 8px;
}
/* #endif */
</style>
